#include "stdafx.h"



//#include "../../utils/Utils.h"

    namespace network
    {

        namespace buffer
        {

            SharedConstBuffer::SharedConstBuffer(std::size_t _size) :
            m_data(new std::vector<unsigned char>((_size < 4) ? 180 : _size)),
            m_buffer(boost::asio::buffer(*m_data, (_size < 4) ? 180 : _size)),
            m_size((_size < 4) ? 180 : _size),
            m_offset(0)
            {
                memset(&((*m_data)[0]), 0, _size);
                put_at_offset(&_size, sizeof (boost::uint16_t), 0);
            }

            SharedConstBuffer::SharedConstBuffer(boost::shared_ptr< std::vector<unsigned char> >& _data) :
            m_data(_data),
            m_buffer(boost::asio::buffer(*m_data)),
            m_size(180),
            m_offset(0)
            {
            }

            SharedConstBuffer::SharedConstBuffer(boost::shared_ptr< std::vector<unsigned char> >& _data, boost::uint16_t _size) :
            m_data(_data),
            m_buffer(boost::asio::buffer(*m_data, _size)),
            m_size(_size),
            m_offset(0)
            {
            }

            SharedConstBuffer::SharedConstBuffer(const SharedConstBuffer& _data) :
            m_data(_data.m_data),
			m_buffer(boost::asio::buffer(*m_data,_data.size())),
            m_size(_data.size()),
            m_offset(0)
            {
            }

            SharedConstBuffer::~SharedConstBuffer()
            {
            }

            const boost::asio::const_buffer* SharedConstBuffer::begin() const
            {
                return &m_buffer;
            }

            const boost::asio::const_buffer* SharedConstBuffer::end() const
            {
                return &m_buffer + 1;
            }

            const unsigned char * SharedConstBuffer::c_data() const
            {
                return &(*m_data)[0];

            }

            const std::size_t SharedConstBuffer::size() const
            {
                return m_size;
            }

            unsigned char* SharedConstBuffer::data() const
            {
                return &(*m_data)[0];
            }

            void SharedConstBuffer::put(std::string _data)
            {
                BOOST_ASSERT((_data.size() + m_offset) <= m_size);
                memcpy((void*) &((*m_data)[m_offset]), (const void*) _data.c_str(), _data.size());
                m_offset += _data.size();
            }

            void SharedConstBuffer::put(const void *_data, std::size_t _size)
            {
                BOOST_ASSERT((_size + m_offset) <= m_size);
                memcpy(&((*m_data)[m_offset]), _data, _size);
                m_offset += _size;

            }

            void SharedConstBuffer::put(std::vector<unsigned char>* _data)
            {
                BOOST_ASSERT((_data->size() + m_offset) <= m_size);
                memcpy((void*) &((*m_data)[m_offset]), (const void*) &((*_data)[0]), _data->size());
                m_offset += _data->size();
            }

            void SharedConstBuffer::put(const std::string& _data, size_t _size)
            {
                BOOST_ASSERT((_size + m_offset) <= m_size);
                //memset((void*)&((*m_data)[m_offset]), 0, _size);
				int i = 0;
				std::string::const_iterator it_string = _data.begin();
				while(  i < _size )
				{
					if( it_string != _data.end())
					{
						(*m_data)[m_offset + i] = *it_string;
						it_string++;
					}
					else
					{
						(*m_data)[m_offset + i] = (char)0;
					}
					i++;
				}
                m_offset += _size;
            }

            void SharedConstBuffer::put_at_offset(const void *_data, std::size_t _size, boost::uint16_t _offset)
            {
                BOOST_ASSERT((_size + _offset) <= m_size);
                memcpy(&((*m_data)[_offset]), _data, _size);
            }

            void SharedConstBuffer::get_at_offset(void *_data, std::size_t _length, boost::uint16_t _offset)
            {
                BOOST_ASSERT((_length + _offset) <= m_size);
                memcpy(_data, &((*m_data)[_offset]), _length);
            }

        } //  namespace buffer
    } //  //	namespace network
